package com.icinfo.cloud.provider.punish.ucase.punishdecide.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.icinfo.cloud.common.security.util.UserUtil;
import com.icinfo.cloud.provider.common.constant.Constant;
import com.icinfo.cloud.provider.common.enums.YesOrNoEnum;
import com.icinfo.cloud.provider.common.exception.BusinessException;
import com.icinfo.cloud.provider.common.qr.service.IQrService;
import com.icinfo.cloud.provider.common.utils.BaseUtil;
import com.icinfo.cloud.provider.punish.common.datareport.enums.ReportDataTypeEnum;
import com.icinfo.cloud.provider.punish.common.datareport.model.CaseDataReportRecord;
import com.icinfo.cloud.provider.punish.common.datareport.service.ICaseDataReportRecordService;
import com.icinfo.cloud.provider.punish.config.dto.CompareDiscretionDto;
import com.icinfo.cloud.provider.punish.config.dto.CompareSingleDiscretionDto;
import com.icinfo.cloud.provider.punish.config.service.IConfigOrgRegulatoryDiscretionRuleHisService;
import com.icinfo.cloud.provider.punish.config.vo.DiscretionHisVo;
import com.icinfo.cloud.provider.punish.ucase.casemain.dto.AppendixDto;
import com.icinfo.cloud.provider.punish.ucase.casemain.dto.CaseDocumentRecordQueryDto;
import com.icinfo.cloud.provider.punish.ucase.casemain.dto.CaseMainDetailAuxiliaryInfoRequest;
import com.icinfo.cloud.provider.punish.ucase.casemain.enums.HandleTypeEnum;
import com.icinfo.cloud.provider.punish.ucase.casemain.enums.PartiesReasonTypeEnum;
import com.icinfo.cloud.provider.punish.ucase.casemain.enums.PunishKindsEnum;
import com.icinfo.cloud.provider.punish.ucase.casemain.mapper.*;
import com.icinfo.cloud.provider.punish.ucase.casemain.model.*;
import com.icinfo.cloud.provider.punish.ucase.casemain.service.*;
import com.icinfo.cloud.provider.punish.ucase.casemain.vo.CaseDocumentRecordDetailVo;
import com.icinfo.cloud.provider.punish.ucase.casemain.vo.CaseDocumentRecordVo;
import com.icinfo.cloud.provider.punish.ucase.casemain.vo.CaseMainInfoVo;
import com.icinfo.cloud.provider.punish.ucase.casemain.vo.CasePartiesRecordVo;
import com.icinfo.cloud.provider.punish.ucase.payment.dto.PublicOpenPayH5ModelDto;
import com.icinfo.cloud.provider.punish.ucase.payment.mapper.CasePaymentMainRecordMapper;
import com.icinfo.cloud.provider.punish.ucase.payment.model.CasePaymentMainRecord;
import com.icinfo.cloud.provider.punish.ucase.punishdecide.dto.*;
import com.icinfo.cloud.provider.punish.ucase.punishdecide.service.IPunishDecideService;
import com.icinfo.cloud.provider.punish.ucase.punishdecide.vo.PublicityInfoVo;
import com.icinfo.cloud.xzcf.provider.member.userinfo.dto.UserDTO;
import com.icinfo.framework.mybatis.mapper.entity.Example;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 描述：处罚决定接口实现类
 *
 * @author xiangyuyu
 * @date 2022/2/17 09:06
 */
@Service
@Slf4j
public class PunishDecideServiceImpl implements IPunishDecideService {
    @Value("${payment.url}")
    private String paymentUrl;
    @Value("${payment.id}")
    private String paymentId;
    @Resource
    private IQrService iQrService;
    @Resource
    private CaseMainInfoMapper caseMainInfoMapper;
    @Resource
    private CaseMainDetailInfoMapper caseMainDetailInfoMapper;
    @Resource
    private CaseAppendixRecordMapper caseAppendixRecordMapper;
    @Resource
    private CaseMainDetailAuxiliaryInfoMapper caseMainDetailAuxiliaryInfoMapper;
    @Resource
    private ICaseAppendixRecordService caseAppendixRecordService;
    @Resource
    private CasePartiesRecordMapper casePartiesRecordMapper;
    @Resource
    private CaseReasonMainRecordMapper caseReasonMainRecordMapper;
    @Resource
    private ICaseMainInfoService caseMainInfoService;
    @Resource
    private ICasePartiesRecordService casePartiesRecordService;
    @Resource
    private ICaseDocumentRecordService caseDocumentRecordService;
    @Resource
    private ICaseMainDetailAuxiliaryInfoService caseMainDetailAuxiliaryInfoService;
    @Resource
    private ICaseDataReportRecordService caseDataReportRecordService;
    @Resource
    private CaseDocumentRecordMapper caseDocumentRecordMapper;
    @Resource
    private CasePaymentMainRecordMapper casePaymentMainRecordMapper;
    @Value("${paymentCq.publicOpenPayH5Url}")
    private String publicOpenPayH5Url;

    @Resource
    private IConfigOrgRegulatoryDiscretionRuleHisService configOrgRegulatoryDiscretionRuleHisService;


    /**
     * 描述：【V1.0.0】描述：获取缴款支付信息
     *
     * @param paymentSlipNumber 缴款单号
     * @return Map<String, String> 缴款支付信息
     * @author xiangyuyu
     * @date 2022-03-02 14:38
     */
    @Override
    public Map<String, String> getPaymentInfo(String paymentSlipNumber) {
        //生成二维码信息
        /*String qrKeyInfo = paymentUrl + "?jkdh=" + paymentSlipNumber + "&id=" + paymentId;
        log.info("qrKeyInfo:{}", qrKeyInfo);
        //获取二维码Base64信息
        QrCodeQueryDto queryDto = new QrCodeQueryDto();
        queryDto.setQrKeyInfo(qrKeyInfo);
        String qrBase64 = iQrService.generateQrCode(queryDto, null);
        //base64转oss地址处理
        String qrUrl = iQrService.base64ToOssUrl(qrBase64);
        Map<String, String> paymentInfo = new HashMap<>(2);
        paymentInfo.put("paymentSlipNumber", paymentSlipNumber);
        paymentInfo.put("qrBase64", qrBase64);
        paymentInfo.put("qrUrl", qrUrl);*/
        Example example = new Example(CasePaymentMainRecord.class);
        example.createCriteria().andEqualTo("noticeNo", paymentSlipNumber);
        List<CasePaymentMainRecord> casePaymentMainRecords=casePaymentMainRecordMapper.selectByExample(example);
        if(ObjectUtils.isEmpty(casePaymentMainRecords)){
            throw new BusinessException("获取支付信息失败！案件缴费主要信息记录表数据为空");
        }
        CasePaymentMainRecord casePaymentMainRecord=casePaymentMainRecords.get(0);
        Map<String, String> paymentInfo = new HashMap<>(2);
        paymentInfo.put("paymentSlipNumber", paymentSlipNumber);

        //获取支付二维码
        PublicOpenPayH5ModelDto publicOpenPayH5ModelDto=new PublicOpenPayH5ModelDto();
        publicOpenPayH5ModelDto.setDocNumber(paymentSlipNumber);
        publicOpenPayH5ModelDto.setDeptId(casePaymentMainRecord.getEnterCode());
        publicOpenPayH5ModelDto.setEffectiveTime(43200);//todo 后续需要调整有效时间
        JSONObject jsonObject =(JSONObject)JSONObject.toJSON(publicOpenPayH5ModelDto);
        try {
            String publicOpenPayH5ResponseVoStr=BaseUtil.post(publicOpenPayH5Url, jsonObject);
            JSONObject publicOpenPayH5ResponseVoJsonObject = JSONObject.parseObject(publicOpenPayH5ResponseVoStr);
            paymentInfo.put("qrBase64", publicOpenPayH5ResponseVoJsonObject.getString("qrCode"));
            paymentInfo.put("qrUrl", publicOpenPayH5ResponseVoJsonObject.getString("h5PayUrl"));
        }catch (Exception exc){
            exc.printStackTrace();
            throw new BusinessException("获取缴款二维码失败");
        }
        return paymentInfo;
    }
    /**
     * 获取处罚决定表单数据
     * @author liyafeng
     * @date 2022/5/20
      * @param decideFormDto
     * @return {@link PunishDecideFormVo}
     */
    @Override
    public PunishDecideFormVo getDecideFormBaseinfo(DecideFormDto decideFormDto) {
        PunishDecideFormVo vo=new PunishDecideFormVo();
        //查询案件主表，获取案由当事人类型
        CaseMainInfo caseMainInfo=caseMainInfoMapper.selectByPrimaryKey(decideFormDto.getCaseId());
        CaseMainDetailInfo caseMainDetailInfo=caseMainDetailInfoMapper.selectByPrimaryKey(decideFormDto.getCaseId());
        String partiesReasonType=caseMainInfo.getCasePartiesReasonType();
        String handleType=caseMainInfo.getHandleType();
        if(Constant.STRING_0.equals(handleType)||Constant.STRING_1.equals(handleType)){
            //单案由单当事人 或者多当事人合并处罚 或者 多案由
            CaseMainDetailInfo detailInfo=caseMainDetailInfoMapper.selectByPrimaryKey(decideFormDto.getCaseId());
            BeanUtils.copyProperties(detailInfo,vo);
            //获取附件
            List<AppendixDto> appendixList=getAppendixList(decideFormDto,partiesReasonType,"");
            vo.setAppendixList(appendixList);
            //获取决定处理内容
            Example example=new Example(CaseMainDetailAuxiliaryInfo.class);
            example.createCriteria().andEqualTo("caseId",decideFormDto.getCaseId());
            List<CaseMainDetailAuxiliaryInfo> caseMainDetailAuxiliaryInfos=caseMainDetailAuxiliaryInfoMapper.selectByExample(example);
            if(CollectionUtil.isNotEmpty(caseMainDetailAuxiliaryInfos)){
                vo.setDisposeContext(caseMainDetailAuxiliaryInfos.get(0).getDisposeContext());
            }
            // 将合并处罚的违法情形填入
            vo.setDiscretionHisVo(configOrgRegulatoryDiscretionRuleHisService.getDiscretionHisByRuleHisId(caseMainDetailInfo.getIllegalSituation()));
        }else if(Constant.STRING_2.equals(handleType)){
            //多当事人 分别处罚
            Example example=new Example(CaseMainDetailAuxiliaryInfo.class);
            example.createCriteria().andEqualTo("caseId",decideFormDto.getCaseId()).andEqualTo("partyId",decideFormDto.getPartyId());
            List<CaseMainDetailAuxiliaryInfo> caseMainDetailAuxiliaryInfos=caseMainDetailAuxiliaryInfoMapper.selectByExample(example);
            List<DecideMultiple> decideMultipleList=new ArrayList<>();
            if(null!=caseMainDetailAuxiliaryInfos&&caseMainDetailAuxiliaryInfos.size()>0){
                //DecideMultiple decideMultiple=new DecideMultiple();
                CaseMainDetailAuxiliaryInfo caseMainDetailAuxiliaryInfo=caseMainDetailAuxiliaryInfos.get(0);
                BeanUtils.copyProperties(caseMainDetailAuxiliaryInfo,vo);
                List<AppendixDto> appendixDtoList=getAppendixList(decideFormDto,partiesReasonType,caseMainDetailAuxiliaryInfo.getCaseReasonId());
                vo.setAppendixList(appendixDtoList);
                // 将当前当事人的违法情形填入
                vo.setDiscretionHisVo(configOrgRegulatoryDiscretionRuleHisService.getDiscretionHisByRuleHisId(caseMainDetailAuxiliaryInfo.getIllegalSituation()));
                //decideMultipleList.add(decideMultiple);
            }
            //vo.setDecideMultipleList(decideMultipleList);
        }
        //多案由 每个案由查询
        if(Constant.STRING_2.equals(partiesReasonType)){
            Example example=new Example(CaseMainDetailAuxiliaryInfo.class);
            example.createCriteria().andEqualTo("caseId",decideFormDto.getCaseId());
            List<CaseMainDetailAuxiliaryInfo> caseMainDetailAuxiliaryInfos=caseMainDetailAuxiliaryInfoMapper.selectByExample(example);
            // 设置单独的处罚决定信息
            vo.setDecideMultipleList(getDecideMultipleList(caseMainDetailAuxiliaryInfos, decideFormDto, partiesReasonType));
        }
        //拼接showContent
        String showContent=getShowContent(caseMainInfo,caseMainDetailInfo,decideFormDto);
        vo.setShowContent(showContent);
        return vo;
    }

    private List<DecideMultiple> getDecideMultipleList(List<CaseMainDetailAuxiliaryInfo> auxiliaryInfoList, DecideFormDto decideFormDto, String partiesReasonType) {
        // 得到违法情形的ruleHisId
        List<String> ruleHisIds = auxiliaryInfoList.stream()
                .map(CaseMainDetailAuxiliaryInfo::getIllegalSituation)
                .filter(StrUtil::isNotBlank).distinct().collect(Collectors.toList());
        // 得到具体的自由裁量信息 key(ruleHisId) -> value(DiscretionHisVo)
        Map<String, DiscretionHisVo> discretionHisByRuleHisIds = configOrgRegulatoryDiscretionRuleHisService.getDiscretionHisByRuleHisIds(ruleHisIds);
        return auxiliaryInfoList.stream()
                .map(a -> convertDecideMultiple(a, discretionHisByRuleHisIds.get(a.getIllegalSituation()), decideFormDto, partiesReasonType))
                .collect(Collectors.toList());
    }

    /**
     * 转换当事人处罚信息
     */
    private DecideMultiple convertDecideMultiple(CaseMainDetailAuxiliaryInfo info, DiscretionHisVo discretionHisVo, DecideFormDto decideFormDto, String partiesReasonType){
        DecideMultiple decideMultiple = new DecideMultiple();
        BeanUtils.copyProperties(info,decideMultiple);
        decideMultiple.setCaseReason(info.getCaseReasonName());
        decideMultiple.setCaseReasonId(info.getCaseReasonId());
        List<AppendixDto> appendixDtoList=getAppendixList(decideFormDto,partiesReasonType,info.getCaseReasonId());
        decideMultiple.setAppendixList(appendixDtoList);
        decideMultiple.setDiscretionHisVo(discretionHisVo);
        return decideMultiple;
    }


    /**
     *拼接showContent
     * @author liyafeng
     * @date 2022/5/28
      * @param caseMainInfo
     * @param caseMainDetailInfo
     * @param decideFormDto
     * @return {@link String}
     */
    private String getShowContent(CaseMainInfo caseMainInfo, CaseMainDetailInfo caseMainDetailInfo, DecideFormDto decideFormDto) {
        //当事人
        String partyNames="";
        //案件发生时间
        String caseHappenTime=DateTimeFormatter.ofPattern("yyyy年M月d日").format(caseMainDetailInfo.getCaseHappenTime());
        //案由
        String caseReasons="";
        //违则
        String IllegalBasis="";
        //罚则
        String punishBasis="";
        String caseId = decideFormDto.getCaseId();
        String handType=caseMainInfo.getHandleType();
        String partyId=decideFormDto.getPartyId();
        List<CasePartiesRecordVo> casePartiesRecords = casePartiesRecordService.getCasePartiesInfo(caseId);
        if (HandleTypeEnum.PART_PUNISH.getCode().equals(handType)) {
            //多当事人分别处罚
            for (CasePartiesRecordVo record : casePartiesRecords) {
                if (partyId.equals(record.getPartyId())) {
                    partyNames = record.getPartyName();
                    break;
                }
            }
        } else if (HandleTypeEnum.MERGE_PUNISH.getCode().equals(handType)) {
            //多当事人合并处罚
            for (CasePartiesRecordVo record : casePartiesRecords) {
                partyNames += record.getPartyName() + "、";
            }
            if (!ObjectUtils.isEmpty(partyNames) && partyNames.endsWith("、")) {
                partyNames = partyNames.substring(0, partyNames.length() - 1);
            }
        } else {
            //单当事人
            partyNames = casePartiesRecords.get(Constant.INTEGER_0).getPartyName();
        }
        Example reasonExample=new Example(CaseReasonMainRecord.class);
        reasonExample.createCriteria().andEqualTo("caseId",decideFormDto.getCaseId()).andEqualTo("status","1");
        List<CaseReasonMainRecord> caseReasonMainRecords=caseReasonMainRecordMapper.selectByExample(reasonExample);
        for (CaseReasonMainRecord caseReasonMainRecord:caseReasonMainRecords) {
            if(StringUtils.isEmpty(caseReasons)){
                //案由
                caseReasons=caseReasonMainRecord.getCaseReasonName();
                //违则
                IllegalBasis=caseReasonMainRecord.getIllegalBasis();
                //罚则
                punishBasis=caseReasonMainRecord.getPunishBasis();
            }else{
                //案由
                caseReasons=caseReasons+"、"+caseReasonMainRecord.getCaseReasonName();
                //违则
                IllegalBasis=IllegalBasis+"、"+caseReasonMainRecord.getIllegalBasis();
                //罚则
                punishBasis=punishBasis+"、"+caseReasonMainRecord.getPunishBasis();
            }
        }
        String showContent="当事人"+partyNames+"于"+caseHappenTime+"在"+caseMainDetailInfo.getCaseHappenAddressDetail()
                +"实施了"+caseReasons+"的行为,违反了"+IllegalBasis+
                ",依据"+punishBasis+",作出如下行政处罚：";
        return showContent;
    }

    /**
     * 保存处罚决定表单数据
     * @author liyafeng
     * @date 2022/5/23
      * @param punishDecideFormDto
     * @return {@link int}
     */
    @Override
    @Transactional(rollbackFor = {Error.class,Exception.class})
    public int saveDecideFormBaseinfo(PunishDecideFormDto punishDecideFormDto) {

        if (org.apache.commons.lang3.StringUtils.isNoneBlank(punishDecideFormDto.getDraftPunishMoney(),punishDecideFormDto.getAddPunishMoney())){
            try {
                BigDecimal draftPunishMoney = new BigDecimal(punishDecideFormDto.getDraftPunishMoney());
                BigDecimal addPunishMoney = new BigDecimal(punishDecideFormDto.getAddPunishMoney());
                if (addPunishMoney.compareTo(draftPunishMoney) == 1){
                    throw new BusinessException("加处罚款金额不可大于罚款金额");
                }
            }catch (NumberFormatException e){
                throw new BusinessException("请输入正确的金额数字");
            }
        }
        int num=0;
        CaseMainInfo caseMainInfo = caseMainInfoMapper.selectByPrimaryKey(punishDecideFormDto.getCaseId());
        String partiesReasonType = caseMainInfo.getCasePartiesReasonType();
        String handleType = caseMainInfo.getHandleType();
        // 校验多当事人、多案由、或者单当事人单案由的违法情形数据
        checkAmount(punishDecideFormDto, partiesReasonType, handleType);
        if(!Constant.STRING_2.equals(handleType)){
            //不为分别处罚 则更新案件详情表
            CaseMainDetailInfo updateCaseMainDetailInfo=new CaseMainDetailInfo();
            BeanUtils.copyProperties(punishDecideFormDto,updateCaseMainDetailInfo);
            num=caseMainDetailInfoMapper.updateByPrimaryKeySelective(updateCaseMainDetailInfo);
            try {
                //单当事人单案由 更新补充表数据
                CaseMainDetailAuxiliaryInfo caseMainDetailAuxiliaryInfo = new CaseMainDetailAuxiliaryInfo();
                BeanUtils.copyProperties(punishDecideFormDto,caseMainDetailAuxiliaryInfo);
                caseMainDetailAuxiliaryInfo.setCaseId(punishDecideFormDto.getCaseId());
                caseMainDetailAuxiliaryInfoService.editSpecialParamSingle(caseMainDetailAuxiliaryInfo);
            }catch (Exception e){
                e.printStackTrace();
            }

        }
        if(Constant.STRING_2.equals(partiesReasonType)){
            //多案由
            List<DecideMultiple> decideMultipleList=punishDecideFormDto.getDecideMultipleList();
            for (DecideMultiple decideMultiple:decideMultipleList) {
                CaseMainDetailAuxiliaryInfo updateCaseMainDetailAuxiliaryInfo=new CaseMainDetailAuxiliaryInfo();
                updateCaseMainDetailAuxiliaryInfo.setDisposeContext(punishDecideFormDto.getDisposeContext());
                BeanUtils.copyProperties(decideMultiple,updateCaseMainDetailAuxiliaryInfo);
                num=caseMainDetailAuxiliaryInfoMapper.updateByPrimaryKeySelective(updateCaseMainDetailAuxiliaryInfo);
            }
        }
        if(Constant.STRING_3.equals(partiesReasonType)&&Constant.STRING_2.equals(handleType)){
            Example example=new Example(CaseMainDetailAuxiliaryInfo.class);
            example.createCriteria().andEqualTo("caseId",punishDecideFormDto.getCaseId()).andEqualTo("partyId",punishDecideFormDto.getPartyId());
            List<CaseMainDetailAuxiliaryInfo> caseMainDetailAuxiliaryInfos=caseMainDetailAuxiliaryInfoMapper.selectByExample(example);
            if(null!=caseMainDetailAuxiliaryInfos&&caseMainDetailAuxiliaryInfos.size()>0){
                CaseMainDetailAuxiliaryInfo caseMainDetailAuxiliaryInfo=caseMainDetailAuxiliaryInfos.get(0);
                CaseMainDetailAuxiliaryInfo updateCaseMainDetailAuxiliaryInfo=new CaseMainDetailAuxiliaryInfo();
                updateCaseMainDetailAuxiliaryInfo.setId(caseMainDetailAuxiliaryInfo.getId());
                BeanUtils.copyProperties(punishDecideFormDto,updateCaseMainDetailAuxiliaryInfo);
                num=caseMainDetailAuxiliaryInfoMapper.updateByPrimaryKeySelective(updateCaseMainDetailAuxiliaryInfo);
            }
        }
        //附件保存
        saveAppendixDto(punishDecideFormDto,partiesReasonType,handleType);
        return num;
    }

    /**
     * 检查处罚金额是否满足裁量信息
     */
    private void checkAmount(PunishDecideFormDto dto, String casePartiesReasonType, String handleType) {

        // 单当事人单案由
        if (Constant.STRING_1.equals(casePartiesReasonType) && dto.getPunishKinds().contains(PunishKindsEnum.PunishKind_2.getDes())) {
            structureSingletonCompareForPunishDecide(dto);
        }
        // 多案由单当事人
        if (Constant.STRING_2.equals(casePartiesReasonType)) {
            structureCompareForPunishDecide(dto);
        }
        // 单案由多当事人 合并处罚  罚款
        if (Constant.STRING_3.equals(casePartiesReasonType)
                && Constant.STRING_1.equals(handleType)
                && dto.getPunishKinds().contains(PunishKindsEnum.PunishKind_2.getDes())) {
            structureSingletonCompareForPunishDecide(dto);
        }
        // 单案由多当事人 分别处罚
        if (Constant.STRING_3.equals(casePartiesReasonType) && Constant.STRING_2.equals(handleType)){
            structureCompareForPunishDecide(dto);
        }
    }

    /**
     * 单当事人单案由 或 单案由多当事人合并处罚 的裁量参数组装
     */
    private void structureSingletonCompareForPunishDecide(PunishDecideFormDto dto) {
        DiscretionHisVo discretionHisVo = dto.getDiscretionHisVo();
        if (Objects.isNull(discretionHisVo)){
            return;
        }
        CompareSingleDiscretionDto param = new CompareSingleDiscretionDto(discretionHisVo.getRuleHisId(), dto.getDraftPunishMoney());
        configOrgRegulatoryDiscretionRuleHisService.verifySingleDiscretionAmount(param);
    }

    /**
     * 多案由单当事人 或 单案由多当事人分别处罚 的裁量参数组装
     */
    private void structureCompareForPunishDecide(PunishDecideFormDto dto) {
        // 裁量校验参数初始化
        CompareDiscretionDto compareParam = new CompareDiscretionDto();

        List<DecideMultiple> decideMultipleList = dto.getDecideMultipleList();
        List<String> discretionIds = decideMultipleList.stream()
                .filter(r -> r.getPunishKinds().contains(PunishKindsEnum.PunishKind_2.getDes()) && Objects.nonNull(r.getDiscretionHisVo()))
                .map(p -> p.getDiscretionHisVo().getRuleHisId()).collect(Collectors.toList());
        Map<String, String> punishInfoMap = decideMultipleList.stream()
                .filter(r -> r.getPunishKinds().contains(PunishKindsEnum.PunishKind_2.getDes()) && Objects.nonNull(r.getDiscretionHisVo()))
                .collect(Collectors.toMap(p -> p.getDiscretionHisVo().getRuleHisId(), DecideMultiple::getDraftPunishMoney));
        compareParam.setDiscretionRuleHisIds(discretionIds);
        compareParam.setPunishInfoMap(punishInfoMap);
        configOrgRegulatoryDiscretionRuleHisService.verifyDiscretionAmount(compareParam);
    }

    /**
     * 附件保存
     * @author liyafeng
     * @date 2022/5/23
      * @param punishDecideFormDto
     * @param partiesReasonType
     * @param handleType
     * @return
     */
    private void saveAppendixDto(PunishDecideFormDto punishDecideFormDto,String partiesReasonType, String handleType) {
        CaseMainInfo caseMainInfo=caseMainInfoMapper.selectByPrimaryKey(punishDecideFormDto.getCaseId());
        if(Constant.STRING_1.equals(partiesReasonType)){
            caseAppendixRecordService.removeCaseAppendixRecordByCaseIdAndCatalogCode(punishDecideFormDto.getCaseId(),punishDecideFormDto.getDocCatalogCode());
            List<AppendixDto> list = punishDecideFormDto.getAppendixList();
            for (AppendixDto appendixDto:list) {
                CaseAppendixRecord record = new CaseAppendixRecord();
                record.setCaseId(punishDecideFormDto.getCaseId());
                record.setCaseStageCode(caseMainInfo.getCaseCurrentStageCode());
                record.setCaseStageName(caseMainInfo.getCaseCurrentStageName());
                record.setAppendixUrl(appendixDto.getAppendixUrl());
                record.setAppendixTypeId(appendixDto.getAppendixTypeId());
                record.setAppendixName(appendixDto.getAppendixName());
                record.setCaseLinkCode(caseMainInfo.getCaseCurrentLinkCode());
                record.setCaseLinkName(caseMainInfo.getCaseCurrentLinkName());
                record.setDocumentCatalogCode(punishDecideFormDto.getDocCatalogCode());
                record.setPartyId(null);
                record.setCaseReasonId(null);
                caseAppendixRecordService.saveCaseAppendixRecord(record);
            }
        }else if(Constant.STRING_2.equals(partiesReasonType)){
            List<DecideMultiple> decideMultiples=punishDecideFormDto.getDecideMultipleList();
            caseAppendixRecordService.removeCaseAppendixRecordByCaseIdAndCatalogCode(punishDecideFormDto.getCaseId(),punishDecideFormDto.getDocCatalogCode());
            for (DecideMultiple decideMultiple:decideMultiples) {
                CaseMainDetailAuxiliaryInfo caseMainDetailAuxiliaryInfo=caseMainDetailAuxiliaryInfoMapper.selectByPrimaryKey(decideMultiple);
                List<AppendixDto> list = decideMultiple.getAppendixList();
                if (null!=list&&list.size()>0){
                    for (AppendixDto appendixDto : list) {
                        CaseAppendixRecord record = new CaseAppendixRecord();
                        record.setCaseId(punishDecideFormDto.getCaseId());
                        record.setCaseStageCode(caseMainInfo.getCaseCurrentStageCode());
                        record.setCaseStageName(caseMainInfo.getCaseCurrentStageName());
                        record.setAppendixUrl(appendixDto.getAppendixUrl());
                        record.setAppendixTypeId(appendixDto.getAppendixTypeId());
                        record.setAppendixName(appendixDto.getAppendixName());
                        record.setCaseLinkCode(caseMainInfo.getCaseCurrentLinkCode());
                        record.setCaseLinkName(caseMainInfo.getCaseCurrentLinkName());
                        record.setDocumentCatalogCode(punishDecideFormDto.getDocCatalogCode());
                        record.setPartyId(caseMainDetailAuxiliaryInfo.getPartyId());
                        record.setCaseReasonId(caseMainDetailAuxiliaryInfo.getCaseReasonId());
                        caseAppendixRecordService.saveCaseAppendixRecord(record);
                    }
                }
            }
        }else if(Constant.STRING_3.equals(partiesReasonType)){
            caseAppendixRecordService.removeCaseAppendixRecordByCaseIdAndCatalogCodeAndPartyId(punishDecideFormDto.getCaseId(),punishDecideFormDto.getDocCatalogCode(),punishDecideFormDto.getPartyId());
            Example example=new Example(CaseMainDetailAuxiliaryInfo.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("caseId",punishDecideFormDto.getCaseId());
            String partyId = punishDecideFormDto.getPartyId();
            if(!ObjectUtils.isEmpty(partyId)){
                criteria.andEqualTo("partyId",partyId);
            }
            List<CaseMainDetailAuxiliaryInfo> caseMainDetailAuxiliaryInfos= caseMainDetailAuxiliaryInfoMapper.selectByExample(example);
            if(null!=caseMainDetailAuxiliaryInfos&&caseMainDetailAuxiliaryInfos.size()>0){
                CaseMainDetailAuxiliaryInfo caseMainDetailAuxiliaryInfo=caseMainDetailAuxiliaryInfos.get(0);
                List<AppendixDto> list = punishDecideFormDto.getAppendixList();
                for (AppendixDto appendixDto:list) {
                    CaseAppendixRecord record = new CaseAppendixRecord();
                    record.setCaseId(punishDecideFormDto.getCaseId());
                    record.setCaseStageCode(caseMainInfo.getCaseCurrentStageCode());
                    record.setCaseStageName(caseMainInfo.getCaseCurrentStageName());
                    record.setAppendixUrl(appendixDto.getAppendixUrl());
                    record.setAppendixTypeId(appendixDto.getAppendixTypeId());
                    record.setAppendixName(appendixDto.getAppendixName());
                    record.setCaseLinkCode(caseMainInfo.getCaseCurrentLinkCode());
                    record.setCaseLinkName(caseMainInfo.getCaseCurrentLinkName());
                    record.setDocumentCatalogCode(punishDecideFormDto.getDocCatalogCode());
                    record.setPartyId(caseMainDetailAuxiliaryInfo.getPartyId());
                    record.setCaseReasonId(caseMainDetailAuxiliaryInfo.getCaseReasonId());
                    caseAppendixRecordService.saveCaseAppendixRecord(record);
                }
            }

        }


    }
    /**
     *附件获取
     * @author liyafeng
     * @date 2022/5/23
      * @param decideFormDto
     * @param partiesReasonType
     * @param caseReasonId
     * @return {@link List< AppendixDto>}
     */
    private List<AppendixDto> getAppendixList(DecideFormDto decideFormDto, String partiesReasonType, String caseReasonId) {
        Example appendixExample=new Example(CaseAppendixRecord.class);
        if(Constant.STRING_1.equals(partiesReasonType)){
            //单案由单当事人
            appendixExample.createCriteria().andEqualTo("caseId",decideFormDto.getCaseId()).andEqualTo("documentCatalogCode",decideFormDto.getDocumentCatalogCode()).andEqualTo("isDelete","0").andEqualTo("appendixStatus",Constant.STRING_1);
        }else if(Constant.STRING_2.equals(partiesReasonType)){
            //多案由单当事人
            appendixExample.createCriteria().andEqualTo("caseId",decideFormDto.getCaseId()).andEqualTo("documentCatalogCode",decideFormDto.getDocumentCatalogCode()).andEqualTo("isDelete","0").andEqualTo("caseReasonId",caseReasonId).andEqualTo("appendixStatus",Constant.STRING_1);
        }else if(Constant.STRING_3.equals(partiesReasonType)){
            //单案由多当事人
            appendixExample.createCriteria().andEqualTo("caseId",decideFormDto.getCaseId()).andEqualTo("documentCatalogCode",decideFormDto.getDocumentCatalogCode()).andEqualTo("isDelete","0").andEqualTo("partyId",decideFormDto.getPartyId()).andEqualTo("appendixStatus",Constant.STRING_1);
        }

        List<CaseAppendixRecord> caseAppendixRecords=caseAppendixRecordMapper.selectByExample(appendixExample);
        List<AppendixDto> appendixList=new ArrayList<>();
        for (CaseAppendixRecord caseAppendixRecord:caseAppendixRecords) {
            AppendixDto appendixDto=new AppendixDto();
            appendixDto.setAppendixName(caseAppendixRecord.getAppendixName());
            appendixDto.setAppendixTypeId(caseAppendixRecord.getAppendixTypeId());
            appendixDto.setAppendixUrl(caseAppendixRecord.getAppendixUrl());
            appendixList.add(appendixDto);
        }
        return appendixList;
    }


    /**
     * 描述：生成业务单号
     *
     * @return String 缴款单号
     * @author xiangyuyu
     * @date 2022-03-12 19:40
     */
    public String generatePaymentServiceNumber() {
        UserDTO userInfo = UserUtil.getUserInfo();
        String areaCode = "";
        if (!ObjectUtils.isEmpty(userInfo)) {
            areaCode = userInfo.getAreaCode();
            if (ObjectUtils.isEmpty(areaCode)) {
                log.info("未获取到用户区域编码（generatePaymentSlipNumber）");
                return "";
            }
        } else {
            log.info("未获取到用户信息（generatePaymentSlipNumber）");
            throw new BusinessException("登录失效");
        }
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter ymd = DateTimeFormatter.ofPattern("yyyyMMdd");
        DateTimeFormatter hMs = DateTimeFormatter.ofPattern("HHmmss");
        //业务单号：4位区划编码+8位年月日+2位随机数+6位时分秒+2位随机数（3300202109292915513281）
        String ymdStr = now.format(ymd);
        String hMsStr = now.format(hMs);
        log.info("ymdStr:{} hMsStr:{}", ymdStr, hMsStr);
        String paymentServiceNumber = areaCode.substring(0, 4) + ymdStr + BaseUtil.getRandom(2)
                + hMsStr + BaseUtil.getRandom(2);
        log.info("paymentServiceNumber:{}", paymentServiceNumber);
        return paymentServiceNumber;
    }

    /**
     * 描述：处罚决定审批通过后更新业务数据
     *
     * @param caseId              案件id
     * @param catalogCode 文书目录编码
     * @return {@link String} 更新异常信息（空值代表更新成功）
     * @author xiangyuyu
     * @date 2022-03-01 20:34
     */
    @Override
    public String doCaseStageOperate(String caseId, String catalogCode) {
        if (ObjectUtils.isEmpty(caseId)) {
            return "未指定案件id";
        }
        CaseMainInfoVo caseMainInfo = caseMainInfoService.getCaseMainInfo(caseId);
        //判断是否所有当事人是否都已经处罚决定审批通过
        //案件案由类型
        boolean isPartiesPartPunish = caseMainInfoService.checkCaseIsPartiesPartPunish(null, caseMainInfo);
        //默认需要更新
        boolean shouldUpdateCaseVerdictEndTime = true;
        if (isPartiesPartPunish) {
            //查看当事人数量
            List<CasePartiesRecordVo> casePartiesRecordList = casePartiesRecordService.getCasePartiesInfo(caseId);
            int count = casePartiesRecordList.size();
            //查看处罚决定书审批通过的记录数

            CaseDocumentRecordQueryDto queryDto = new CaseDocumentRecordQueryDto();
            queryDto.setCaseId(caseId);
            queryDto.setDocumentKindCode(Constant.STRING_KIND_CODE_CFJDS);
            queryDto.setIsQueryDocumentApprovalTimeNotNull(YesOrNoEnum.YES.getCode());
            List<CaseDocumentRecordVo> documentRecordList = caseDocumentRecordService.getCaseDocumentRecordList(queryDto);
            queryDto.setDocumentKindCode(Constant.STRING_KIND_CODE_BYCFJDS);
            List<CaseDocumentRecordVo> documentRecordOtherList = caseDocumentRecordService.getCaseDocumentRecordList(queryDto);
            if(documentRecordOtherList.size()>0){
                documentRecordOtherList.forEach(e->{
                    documentRecordList.add(e);
                });
            }
            int countApprovalPass = 0;
            if (!ObjectUtils.isEmpty(documentRecordList) && documentRecordList.size() > 0) {
                countApprovalPass = documentRecordList.size();
            }
            if (count != countApprovalPass) {
                shouldUpdateCaseVerdictEndTime = false;
            }
        }
        if (shouldUpdateCaseVerdictEndTime) {
            CaseMainInfo caseInfo = new CaseMainInfo();
            caseInfo.setId(caseId);
            caseInfo.setCaseVerdictEndTime(LocalDateTime.now());
            caseMainInfoMapper.updateByPrimaryKeySelective(caseInfo);
        } else {
            log.info("暂不更新裁决完毕时间，所有当事人并未全部审批通过");
        }
        return null;
    }

    /**
     * 描述： 查询公示信息
     *
     * @author: zhengqiang
     * @date: 2022/7/20
     * @param: publicityInfoQueryDto
     * @return {@link PublicityInfoVo}
     **/
    @Override
    public PublicityInfoVo getPublicityInfo(PublicityInfoQueryDto publicityInfoQueryDto) {
        PublicityInfoVo publicityInfoVo = new PublicityInfoVo();
        String caseId = publicityInfoQueryDto.getCaseId();
        String partyId = publicityInfoQueryDto.getPartyId();
        CaseMainInfoVo caseMainInfo = caseMainInfoService.getCaseMainInfo(caseId);
        String casePartiesReasonType = caseMainInfo.getCasePartiesReasonType();
        String handleType = caseMainInfo.getHandleType();
        if (PartiesReasonTypeEnum.MULTIPLE_PARTIES.getCode().equals(casePartiesReasonType)
                && HandleTypeEnum.PART_PUNISH.getCode().equals(handleType) ){
            if (ObjectUtils.isEmpty(partyId)) {
                throw new BusinessException("多当事人分别处罚时请指定当事人id");
            }
            //多当事人分别处罚时查询案件详情补充表
            CaseMainDetailAuxiliaryInfoRequest request = new CaseMainDetailAuxiliaryInfoRequest(caseId, partyId);
            List<CaseMainDetailAuxiliaryInfo> caseMainDetailAuxiliaryList = caseMainDetailAuxiliaryInfoService.getCaseMainDetailAuxiliaryInfo(request);
            if (!ObjectUtils.isEmpty(caseMainDetailAuxiliaryList)) {
                CaseMainDetailAuxiliaryInfo caseMainDetailAuxiliaryInfo = caseMainDetailAuxiliaryList.get(0);
                BeanUtils.copyProperties(caseMainDetailAuxiliaryInfo, publicityInfoVo);
            }
        } else {
            CaseMainDetailInfo caseMainDetailInfo = caseMainDetailInfoMapper.selectByPrimaryKey(caseId);
            BeanUtils.copyProperties(caseMainDetailInfo, publicityInfoVo);
        }

        //公示相关信息处理
        if (YesOrNoEnum.YES.getCode().equals(publicityInfoVo.getIsPublicity())) {
            //默认未公示
            boolean isAlreadyPublicity = false;
            publicityInfoVo.setIsPublicityText("予以公示");
            //查询处罚决定最新上报记录
            CaseDataReportRecord latestReportRecord = caseDataReportRecordService.getLatestReportRecord(caseId, ReportDataTypeEnum.DECISION.getCode());
            publicityInfoVo.setIsAlreadyPublicity(YesOrNoEnum.NO.getCode());
            publicityInfoVo.setIsAlreadyPublicityText(YesOrNoEnum.NO.getDes());
            if (!ObjectUtils.isEmpty(latestReportRecord)) {
                //校验是否已经公示,通过访问公示地址来判断
                String publicUrl = latestReportRecord.getPublicUrl();
                if (checkPublicUrl(publicUrl)) {
                    isAlreadyPublicity = true;
                    String publicDate = latestReportRecord.getPublicDate().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"));
                    publicityInfoVo.setPublicityDate(publicDate);
                    publicityInfoVo.setIsAlreadyPublicity(YesOrNoEnum.YES.getCode());
                    publicityInfoVo.setIsAlreadyPublicityText(YesOrNoEnum.YES.getDes());
                    publicityInfoVo.setPublicitySite("政务服务网");
                    publicityInfoVo.setPublicityUrl(latestReportRecord.getPublicUrl());
                }
            }

            //未公示处理
            if (!isAlreadyPublicity) {
                //待送达的，在公示地址处展示“文书待送达，暂未公示”，
                //送达后未公示前，在公示地址处展示“已上报浙江政务服务网，待完成公示后在此处查看公示地址”
                CaseDocumentRecordQueryDto queryDto = new CaseDocumentRecordQueryDto();
                queryDto.setCaseId(caseId);
                queryDto.setDocumentKindCode(Constant.STRING_KIND_CODE_CFJDS);
                queryDto.setPartyId(partyId);
                CaseDocumentRecordDetailVo caseDocumentRecordDetailVo = caseDocumentRecordMapper.selectCaseDocumentRecordDetail(queryDto);
                if (!ObjectUtils.isEmpty(caseDocumentRecordDetailVo)) {
                    if (ObjectUtils.isEmpty(caseDocumentRecordDetailVo.getSentTime())) {
                        publicityInfoVo.setPublicityUrl("文书待送达，暂未公示");
                    } else {
                        publicityInfoVo.setPublicityUrl("已上报政务服务网，待完成公示后在此处查看公示地址");
                    }
                }
            }

        } else {
            publicityInfoVo.setIsPublicityText("不予公示");
        }
        return publicityInfoVo;
    }

    /**
     * 描述： 校验公示地址是否存在
     *
     * @author: zhengqiang
     * @date: 2022/7/22
     * @param: url
     * @return {@link boolean}
     **/
    private boolean checkPublicUrl(String url) {
        url=url.replace("https://www.zjzwfw.gov.cn","http://10.145.147.112:8581/proxy/zwfwwGs");
        String response = BaseUtil.sendGETRequest(url, new HashMap<>());
        if (ObjectUtils.isEmpty(response)) {
            return false;
        }
        return true;
    }

}
